using System;
using System.Linq;
using System.Threading.Tasks;
using Admin.NET.Application.Service.ReportForms;
using Admin.NET.Core;
using Furion.DependencyInjection;
using Furion.DynamicApiController;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;

namespace Admin.NET.Application.Service.Cockpit;

/// <summary>
/// 驾驶舱相关接口
/// </summary>
[ApiDescriptionSettings(new string[] { "业务应用" }, Order = 100)]
public class CockpitService : IDynamicApiController, ITransient, IPrivateDependency
{
	private readonly SqlSugarRepository<ElectricMeter> _rep;

	private readonly FinanceService _financeService;

	private readonly EnergyService _energyService;

	public CockpitService(SqlSugarRepository<ElectricMeter> rep, FinanceService financeService, EnergyService energyService)
	{
		_rep = rep;
		_financeService = financeService;
		_energyService = energyService;
	}

	/// <summary>
	/// 获取电表在线率、采集器在线率、电表运行率、房间入住率
	/// </summary>
	/// <returns></returns>
	[HttpGet("/cockpit/rates")]
	public async Task<dynamic> GetRates()
	{
		int metertotal = await _rep.CountAsync((ElectricMeter c) => true);
		int meteronline = await _rep.CountAsync((ElectricMeter c) => c.SignalStatus == 1);
		int meterrun = await _rep.CountAsync((ElectricMeter c) => c.GateStatus == 1);
		int collectortotal = await _rep.Context.Queryable<Admin.NET.Application.Collector>().CountAsync();
		int collectoronline = await (from w in _rep.Context.Queryable<Admin.NET.Application.Collector>()
			where w.Status == 1
			select w).CountAsync();
		int roomtotal = await _rep.Context.Queryable<Room>().CountAsync();
		int roomoccupied = await (from w in _rep.Context.Queryable<Room>()
			where w.OwnerId != null
			select w).CountAsync();
		int arrears = await (from w in _rep.Context.Queryable<Room>()
			where w.Balance < 0m
			select w).CountAsync();
		int arrears20 = await (from w in _rep.Context.Queryable<Room>()
			where w.Balance < 20m
			select w).CountAsync();
		int arrears50 = await (from w in _rep.Context.Queryable<Room>()
			where w.Balance < 50m
			select w).CountAsync();
		int arrears100 = await (from w in _rep.Context.Queryable<Room>()
			where w.Balance < 100m
			select w).CountAsync();
		double meteronlinerate = 0.0;
		double meterrunrate = 0.0;
		if (metertotal != 0)
		{
			meteronlinerate = Math.Round((double)meteronline / ((double)metertotal * 1.0), 2);
			meterrunrate = Math.Round((double)meterrun / ((double)metertotal * 1.0), 2);
		}
		double collectoronlinerate = 0.0;
		if (collectortotal != 0)
		{
			collectoronlinerate = Math.Round((double)collectoronline / ((double)collectortotal * 1.0), 2);
		}
		double roomoccupiedrate = 0.0;
		if (roomtotal != 0)
		{
			roomoccupiedrate = Math.Round((double)roomoccupied / ((double)roomtotal * 1.0), 2);
		}
		return new
		{
			MeterOnlineRate = meteronlinerate,
			MeterRunRate = meterrunrate,
			CollectorOnlineRate = collectoronlinerate,
			RoomOccupiedRate = roomoccupiedrate,
			MeterTotal = metertotal,
			MeterOnline = meteronline,
			MeterRun = meterrun,
			RoomTotal = roomtotal,
			RoomOccupied = roomoccupied,
			Arrears = arrears,
			Arrears20 = arrears20,
			Arrears50 = arrears50,
			Arrears100 = arrears100
		};
	}

	/// <summary>
	/// 获取离线电表的列表
	/// </summary>
	/// <returns></returns>
	[HttpGet("/cockpit/meterofflines")]
	public async Task<dynamic> GetOfflineMeter()
	{
		return await _rep.GetListAsync((ElectricMeter w) => w.SignalStatus == 0);
	}

	/// <summary>
	/// 近30天缴费占比分析
	/// </summary>
	/// <returns></returns>
	[HttpGet("/cockpit/paytypecount")]
	public async Task<dynamic> GetPayTypeCount()
	{
		DateTime now = DateTime.Now;
		DateTime latest30days = now.AddDays(-29.0);
		return (await (from w in _rep.Context.Queryable<PaymentRecord>()
			where w.IsPay == 1 && w.CreateTime >= latest30days && w.CreateTime <= now
			group w by w.PayType into w
			select new
			{
				PayType = w.PayType,
				FeeSum = SqlFunc.AggregateSumNoNull(w.Amount)
			}).ToListAsync()).Select(s => new
		{
			Name = s.PayType.ToString(),
			Value = s.FeeSum
		}).ToList();
	}

	/// <summary>
	/// 近6个月收入统计
	/// </summary>
	/// <returns></returns>
	[HttpGet("/cockpit/getrecent6monthpay")]
	public async Task<dynamic> GetRecent6MonthPay()
	{
		DateTime end = DateTime.Today;
		DateTime begin = end.AddMonths(-5);
		EnergyInput input = new EnergyInput
		{
			Type = 1,
			BeginYear = begin.Year,
			BeginMonth = begin.Month,
			EndYear = end.Year,
			EndMonth = end.Month
		};
		return await _financeService.GetCharts(input);
	}

	/// <summary>
	/// 近6个月能耗统计
	/// </summary>
	/// <returns></returns>
	[HttpGet("/cockpit/getrecent6monthenergy")]
	public async Task<dynamic> GetRecent6MonthEnergy()
	{
		DateTime end = DateTime.Today;
		DateTime begin = end.AddMonths(-5);
		EnergyInput input = new EnergyInput
		{
			Type = 1,
			BeginYear = begin.Year,
			BeginMonth = begin.Month,
			EndYear = end.Year,
			EndMonth = end.Month
		};
		return await _energyService.GetCharts(input);
	}
}
